import type { RequestConfig, RequestOptions } from '@umijs/max';
import { message, notification } from 'antd';

// 错误处理方案： 错误类型
enum ErrorShowType {
  SILENT = 0,
  WARN_MESSAGE = 1,
  ERROR_MESSAGE = 2,
  NOTIFICATION = 3,
  REDIRECT = 9,
}
// 与后端约定的响应数据格式
interface ResponseStructure {
  success: boolean;
  data: any;
  errorCode?: number;
  errorMessage?: string;
  showType?: ErrorShowType;
}

/**
 * @name request 配置，可以配置错误处理
 * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
 * @doc https://umijs.org/docs/max/request#配置
 */
export const requestConfig: RequestConfig = {
  /**
   * @name 错误处理
   * pro 自带的错误处理， 可以在这里做自己的改动
   * @doc https://umijs.org/docs/max/request#配置
   */
  // 错误处理： umi@3 的错误处理方案。
  errorConfig: {
    // 错误抛出,errorThrower 是利用 responseInterceptors 实现的，它的触发条件是: 当 data.success 为 false 时
    errorThrower: (res: any) => {
      const { success, data, errorCode, errorMessage, showType } =
        res as unknown as ResponseStructure;
      if (!success) {
        if (data.msg) notification.error({ message: errorCode || '错误提示', description: data.msg || errorMessage, showProgress: true, pauseOnHover: true })
        else notification.error({ message: errorCode || '错误提示', description: data || errorMessage, showProgress: true, pauseOnHover: true })
      }
    },
    // 错误接收及处理
    errorHandler: (error: any, opts: any) => {
      if (opts?.skipErrorHandler) throw error;
      // 我们的 errorThrower 抛出的错误。
      if (error.name === 'BizError') {
        const errorInfo: ResponseStructure | undefined = error.info;
        if (errorInfo) {
          const { errorMessage, errorCode } = errorInfo;
          switch (errorInfo.showType) {
            case ErrorShowType.SILENT:
              // do nothing
              break;
            case ErrorShowType.WARN_MESSAGE:
              message.warning(errorMessage);
              break;
            case ErrorShowType.ERROR_MESSAGE:
              message.error(errorMessage);
              break;
            case ErrorShowType.NOTIFICATION:
              notification.open({
                description: errorMessage,
                message: errorCode,
              });
              break;
            case ErrorShowType.REDIRECT:
              // TODO: redirect
              break;
            default:
              message.error(errorMessage);
          }
        }
      } else if (error.response) {
        // Axios 的错误
        // 请求成功发出且服务器也响应了状态码，但状态代码超出了 2xx 的范围
        message.error(`Response status:${error.response.status}`);
      } else if (error.request) {
        // 请求已经成功发起，但没有收到响应
        // \`error.request\` 在浏览器中是 XMLHttpRequest 的实例，
        // 而在node.js中是 http.ClientRequest 的实例
        message.error('None response! Please retry.');
      } else {
        // 发送请求时出了点问题
        message.error('Request error, please retry.');
      }
    },
  },

  // 请求拦截器
  requestInterceptors: [
    (config: RequestOptions) => {
      const token = localStorage.getItem('accessToken');
      if (token) {
        config.headers = {
          ...config.headers,
          Authorization: token,
        }
      }
      // 过滤空参数(文本框,填写后再 x 清除后需要'重置',否则会以''值传递)
      if (config.params) {
        Object.keys(config.params).forEach((key) => {
          if (!config.params[key] || config.params[key] === '') {
            delete config.params[key];
          }
        })
      }
      // config.timeout = 10000;
      return { ...config };
    },
  ],

  // 响应拦截器
  responseInterceptors: [
    (response: any) => {
      // 拦截响应数据，进行个性化处理
      // const { data } = response as unknown as ResponseStructure;
      // if (data?.success === false) { // 由 errorThrower 处理
      //     message.error('请求失败！');
      // }
      // console.log(data.data);

      // if (Array.isArray(data.data) && data.data[0].hasOwnProperty('UpdateTime')) {
      //     (data.data as any).forEach((element: any) => {
      //         element['UpdateTimeQQ'] = element['UpdateTime']
      //         delete element['UpdateTime']
      //     })
      // }
      return response;
    },
  ],
};